package com.chatuser.userbase.tool;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.cglib.beans.BeanCopier;


import java.util.concurrent.TimeUnit;


/**
 * 防止缓存过载和考虑性能问题,缓存Cglib的类对象
 *
 * @author cong.zhen
 * @date 2022/05/20
 */
public class ObjectCopyBean {

    private final Long MaxNumSize = 2000L;

    private final Long afterWrite = 1800L;

    private Cache<String, BeanCopier> beanCache = null;

    public static ObjectCopyBean instance(){
        return SingletonObjectCopyBean.instance;
    }

    private static class SingletonObjectCopyBean{
        public static ObjectCopyBean instance = new ObjectCopyBean();
    }

    private ObjectCopyBean(){
        beanCache = CacheBuilder.newBuilder()
                .maximumSize(MaxNumSize)
                .expireAfterWrite(afterWrite, TimeUnit.SECONDS)
                .softValues()
                .build();
    }

    public BeanCopier getCopier(Object source,Object target){
        String beanKey = generateKey(source.getClass(), target.getClass());
        BeanCopier copier = beanCache.getIfPresent(beanKey);

        //双检锁保证单个
        if(copier == null){
            synchronized (ObjectCopyBean.class){
                copier = beanCache.getIfPresent(beanKey);
                if (copier == null) {
                    copier = BeanCopier.create(source.getClass(), target.getClass(),false);
                    beanCache.put(beanKey, copier);
                }
                return copier;
            }
        }

        return copier;
    }

    private String generateKey(Class<?> classSource,Class<?> classTarget) {
        return classSource.toString().concat(classTarget.toString());
    }
}
